package com.gdkj.util;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.config.SocketConfig;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @auther: hejun
 * @date: 2021/3/4
 * @Description: 发送http请求
 */
@Slf4j
public class HttpUtils {

    private static PoolingHttpClientConnectionManager cm;

    private static Integer timeout = 10;

    public static OkHttpClient okHttpClient = new OkHttpClient().newBuilder().
            connectTimeout(timeout, TimeUnit.SECONDS).
            readTimeout(timeout, TimeUnit.SECONDS).
            writeTimeout(timeout, TimeUnit.SECONDS).
            build();

    /**
     * @Author hejun
     * @Description: 发送post请求-ok-http
     * @Date  2021/3/4
     * @param url
     * @param headers
     * @return java.lang.String
     **/
    public static String doPostFormData(String url, Map<String, String> paramsMap, Map<String, String> headers) throws IOException {
        FormBody.Builder formBodyBuilder = new FormBody.Builder();
        for (Map.Entry<String, String> entries :paramsMap.entrySet()) {
            formBodyBuilder.add(entries.getKey(), entries.getValue());
        }
        FormBody formBody = formBodyBuilder.build();
        Request.Builder builder = new Request.Builder();
        for (Map.Entry<String, String> headItem : headers.entrySet()) {
            builder.addHeader(headItem.getKey(), headItem.getValue());
        }
        Request request = builder.post(formBody).url(url).build();
        String resultStr = getResponseString(okHttpClient, request);
        log.info("请求地址为:" +  url + ",请求参数为:" + JSONObject.toJSONString(paramsMap) + ",返回的数据为:" + resultStr);
        return resultStr;
    }

    /**
     * @Author hejun
     * @Description: 发送put请求-ok-http
     * @Date  2021/3/19
     * @param url
     * @param content
     * @return java.lang.String
     **/
    public static String doPutJson(String url, String content) throws IOException {
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody requestBody = RequestBody.create(mediaType, content);
        Request putRequest = new Request.Builder().put(requestBody).url(url).build();
        log.info("put请求地址为:" +  url + "数据为:" + requestBody.toString());
        return getResponseString(okHttpClient, putRequest);
    }

    /**
     * @Author hejun
     * @Description: 发送put请求-ok-http
     * @Date  2021/3/19
     * @param url
     * @param content
     * @return java.lang.String
     **/
    public static String doPostJson(String url, String content, Map<String, String> headers, Integer timeout) throws IOException {
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody requestBody = RequestBody.create(mediaType, content);
        Request.Builder builder = new Request.Builder();
        for (Map.Entry<String, String> headItem : headers.entrySet()) {
            builder.addHeader(headItem.getKey(), headItem.getValue());
        }
        Request putRequest = builder.post(requestBody).url(url).build();
        String resultStr = getResponseString(okHttpClient, putRequest);
        String message = String.format("post请求地址为:%s, headers为:%s, 请求参数为:%s, 返回数据为:%s",
                url, JSONObject.toJSONString(headers), content, resultStr);
        log.info(message);
        return resultStr;
    }

    /**
     * @Author hejun
     * @Description: 发送get请求-ok-http
     * @Date  2021/4/2
     * @param url
     * @return java.lang.String
     **/
    public static String doGet(String url, Integer timeout) throws IOException {
        Request getRequest = new Request.Builder().get().url(url).build();
        log.info("get请求地址为:" +  url);
        return getResponseString(okHttpClient, getRequest);
    }

    /**
     * 处理返回数据
     * @param client
     * @param request
     * @return java.lang.String
     * @throws IOException
     */
    private static String getResponseString(OkHttpClient client, Request request) throws IOException {
        Response putResponse = client.newCall(request).execute();
        ResponseBody responseBody = putResponse.body();
        if (responseBody == null) {
            log.info("返回数据为空");
            return "";
        }
        String resultStr = responseBody.string();
        log.info("返回数据为:" + resultStr);
        return resultStr;
    }


    /**
     * 发送post请求-httpclient
     * @param url
     * @param headers
     * @param params
     * @return  java.lang.String
     * @throws UnsupportedEncodingException
     */
    public static String httpPostRequest(String url, Map<String, Object> headers, String params)
            throws UnsupportedEncodingException {
        HttpPost httpPost = new HttpPost(url);
        for (Map.Entry<String, Object> param : headers.entrySet()) {
            httpPost.addHeader(param.getKey(), String.valueOf(param.getValue()));
        }
        httpPost.setEntity(new StringEntity(params, ContentType.create("application/json", "UTF-8")));
        return getResult(httpPost);
    }

    /**
     * 获取防疫数据
     * @param request
     * @return java.lang.String
     */
    private static String getResult(HttpRequestBase request) {

        RequestConfig.Builder config = RequestConfig.copy(RequestConfig.DEFAULT);
        config.setConnectionRequestTimeout(60000);
        config.setSocketTimeout(60000);
        request.setConfig(config.build());
        // CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpClient httpClient = getHttpClient();
        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(request);
            // response.getStatusLine().getStatusCode();
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                // long len = entity.getContentLength();// -1 表示长度未知
                return EntityUtils.toString(entity);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                // 释放Socket流
                response.close();
                // 释放Connection
                // httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }


    private static void init() {
        if (cm == null) {
            cm = new PoolingHttpClientConnectionManager();
            cm.setMaxTotal(50);// 整个连接池最大连接数
            cm.setDefaultMaxPerRoute(5);// 每路由最大连接数，默认值是2
            SocketConfig sc = SocketConfig.custom().setSoTimeout(60000).build();
            cm.setDefaultSocketConfig(sc);
        }
    }

    /**
     * 通过连接池获取HttpClient
     *
     * @return
     */
    private static CloseableHttpClient getHttpClient() {
        init();
        return HttpClients.custom().setConnectionManager(cm).setConnectionManagerShared(true).build();
    }
}
